/*
 * iic.c
 *
 *  Created on: 2021年8月22日
 *      Author: 86181
 */
#include "iic.h"
#define IIC_SDA_On()     do{GPIO_InitTypeDef GPIO_InitStruct = {0};\
	        					GPIO_InitStruct.Pin = GPIO_PIN_14;\
	        					GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;\
	        					GPIO_InitStruct.Pull = GPIO_NOPULL;\
	        					GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;\
	        					HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);\
	        					}while(0)

#define IIC_SDA_In()        do{GPIO_InitTypeDef GPIO_InitStruct = {0};\
								GPIO_InitStruct.Pin = GPIO_PIN_14;\
								GPIO_InitStruct.Mode = GPIO_MODE_INPUT;\
								GPIO_InitStruct.Pull = GPIO_NOPULL;\
								GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;\
								HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);\
								}while(0)

void IIC_Start()//产生开始信号
{
	IIC_SDA_On();//输出模式
	SCL_H();
	SDA_H();
	delay_us(2);
	SDA_L();
	delay_us(2);
	SCL_L();
}
void IIC_Stop()//产生结束信号
{
	IIC_SDA_On();//输出模式
	SCL_L();
	SDA_L();
	delay_us(2);
	SCL_H();
	delay_us(2);
	SDA_H();
	delay_us(2);
}
uint8_t IIC_Wait_Ack()
{
	uint8_t ucErrTime=0;
	IIC_SDA_In();
	SCL_H();
	while(SDA_Read())
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	SCL_L();
	return 0;
}
void IIC_Ack()//应答模式，SCL高电平时，SDA=0为应答
{
	SCL_L();
	IIC_SDA_On();//输出模式
	SDA_L();
	/*SCL__---
	 *
	 *SDA_____
	 *传输数据0
	*/
	delay_us(2);
	SCL_H();
	delay_us(2);
	SCL_L();
}
void IIC_NAck(void)
{
	SCL_L();
	IIC_SDA_On();//输出模式
	SDA_H();
	/*SCL__---
	 *
	 *SDA-----
	 *传输数据1
	*/
	delay_us(2);
	SCL_H();
	delay_us(2);
	SCL_L();
}
uint8_t IIC_Receive_Byte(uint8_t ack)
{
	uint8_t i,recevie=0;
	IIC_SDA_In();
	for(i=0;i<8;i++)
	{
		SCL_L();
		delay_us(2);
		SCL_H();
		recevie<<=1;
		recevie+=SDA_Read();
		delay_us(2);
	}
	if(ack)
		IIC_Ack();
	else
		IIC_NAck();
	return recevie;
}
void IIC_Send_Byte(uint8_t data)
{
	uint8_t i,txd;
	IIC_SDA_On();
	SCL_L();//拉低时钟线，选择传输的SDA电平，因为数据传输需要在SCL低电平时改变，高电平时输出
	for(i=0;i<8;i++)
	{
		txd=(data&0x80)>>7;//把最高位取出来
		data<<=1;
		if(txd)
			SDA_H();
		else
			SDA_L();
		delay_us(2);
		SCL_H();//开始传输
		delay_us(2);
		SCL_L();
		delay_us(2);
	}
}

